using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using UniversalAdmin.Application.Commands;
using UniversalAdmin.Application.Dto;
using UniversalAdmin.Application.Services;
using UniversalAdmin.Shared.Enums;
using UniversalAdmin.Api.Filters;

/// <summary>
/// 文件管理控制器
/// 使用通用枚举状态码：
/// - ApiStatusCode.SUCCESS (200): 操作成功
/// - ApiStatusCode.BAD_REQUEST (400): 请求参数错误
/// - ApiStatusCode.UNAUTHORIZED (401): 未授权
/// - ApiStatusCode.FORBIDDEN (403): 禁止访问
/// - ApiStatusCode.NOT_FOUND (404): 文件不存在
/// - ApiStatusCode.INTERNAL_ERROR (500): 服务器内部错误
/// </summary>
[ApiController]
[Route("api/files")]
[Authorize]
public class FilesController : ControllerBase
{
    private readonly IAppFileService _fileService;
    public FilesController(IAppFileService fileService) { _fileService = fileService; }

    // 分页+搜索
    [HttpGet]
    [RequirePermission("file.view")] // 需要查看文件权限
    public async Task<ApiResult> Get([FromQuery] int? page = null, [FromQuery] int? size = null, [FromQuery] string? search = null)
    {
        if (page.HasValue && size.HasValue)
        {
            var result = await _fileService.GetPagedAsync(new PagedQuery { Page = page.Value, Size = size.Value, Search = search });
            return new ApiResult { Code = result.Code, Message = result.Message, Data = result.Data, Timestamp = result.Timestamp };
        }
        else
        {
            var result = await _fileService.GetAllAsync(search);
            return new ApiResult { Code = result.Code, Message = result.Message, Data = result.Data, Timestamp = result.Timestamp };
        }
    }

    // 获取单个文件
    [HttpGet("{id}")]
    [RequirePermission("file.view")] // 需要查看文件权限
    public async Task<ApiResult<FileDto>> GetById(Guid id)
        => await _fileService.GetByIdAsync(id);

    // 上传文件
    [HttpPost("upload")]
    [RequirePermission("file.upload")] // 需要上传文件权限
    public async Task<ApiResult<FileDto>> Upload([FromForm] IFormFile file)
    {
        try
        {
            if (file == null || file.Length == 0)
            {
                return ApiResult<FileDto>.Failed((int)ApiStatusCode.BAD_REQUEST, "请选择要上传的文件");
            }

            var result = await _fileService.UploadAsync(file);
            return new ApiResult<FileDto> { Code = result.Code, Message = result.Message, Data = result.Data, Timestamp = result.Timestamp };
        }
        catch (Exception ex)
        {
            return ApiResult<FileDto>.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"上传文件时发生错误: {ex.Message}");
        }
    }

    // 通过文件名直接访问文件
    [HttpGet("download/{fileName}")]
    [AllowAnonymous]
    public async Task<IActionResult> DownloadByFileName(string fileName)
    {
        try
        {
            var filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "uploads", fileName);
            if (!System.IO.File.Exists(filePath))
            {
                return NotFound("文件不存在");
            }

            var fileInfo = new FileInfo(filePath);
            var contentType = GetContentType(Path.GetExtension(filePath));

            // 对于大文件，使用流式传输
            if (fileInfo.Length > 10 * 1024 * 1024) // 10MB
            {
                var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                return File(stream, contentType, fileName);
            }
            else
            {
                // 小文件直接读取
                var fileBytes = await System.IO.File.ReadAllBytesAsync(filePath);
                return File(fileBytes, contentType, fileName);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"下载文件时发生错误: {ex.Message}");
        }
    }

    // 预览文件
    [HttpGet("preview/{id}")]
    [AllowAnonymous] // 预览文件无需权限，允许匿名访问
    public async Task<IActionResult> Preview(Guid id)
    {
        try
        {
            // 获取当前用户ID
            var userIdClaim = User.FindFirst("UserId");
            if (userIdClaim == null || !Guid.TryParse(userIdClaim.Value, out var currentUserId))
            {
                return Unauthorized("用户未登录");
            }

            var result = await _fileService.GetByIdAsync(id);
            if (!result.Succeeded)
            {
                return NotFound(result.Message);
            }

            // 检查文件是否存在
            var filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", result.Data.FilePath);
            if (!System.IO.File.Exists(filePath))
            {
                return NotFound("文件不存在");
            }

            // 获取文件信息
            var fileInfo = new FileInfo(filePath);
            var contentType = result.Data.ContentType ?? GetContentType(Path.GetExtension(filePath));

            // 对于大文件，使用流式传输
            if (fileInfo.Length > 10 * 1024 * 1024) // 10MB
            {
                var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                return File(stream, contentType, result.Data.FileName);
            }
            else
            {
                // 小文件直接读取
                var fileBytes = await System.IO.File.ReadAllBytesAsync(filePath);
                return File(fileBytes, contentType, result.Data.FileName);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"预览文件时发生错误: {ex.Message}");
        }
    }

    // 获取内容类型
    private string GetContentType(string extension)
    {
        return extension.ToLowerInvariant() switch
        {
            ".jpg" or ".jpeg" => "image/jpeg",
            ".png" => "image/png",
            ".gif" => "image/gif",
            ".bmp" => "image/bmp",
            ".pdf" => "application/pdf",
            ".doc" => "application/msword",
            ".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
            ".xls" => "application/vnd.ms-excel",
            ".xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
            ".txt" => "text/plain",
            ".zip" => "application/zip",
            ".rar" => "application/x-rar-compressed",
            _ => "application/octet-stream"
        };
    }

    // 删除文件
    [HttpDelete("{id}")]
    [RequirePermission("file.delete")] // 需要删除文件权限
    public async Task<ApiResult> Delete(Guid id)
    {
        try
        {
            var result = await _fileService.DeleteAsync(id);
            return new ApiResult { Code = result.Code, Message = result.Message, Data = result.Data, Timestamp = result.Timestamp };
        }
        catch (Exception ex)
        {
            return ApiResult.Failed((int)ApiStatusCode.INTERNAL_ERROR, $"删除文件时发生错误: {ex.Message}");
        }
    }
} 